package com.topisv.tms.service.stock.moveStock;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.User;
import com.topisv.tms.entity.stock.CusStock;
import com.topisv.tms.entity.stock.moveStock.MoveStockBill;
import com.topisv.tms.entity.stock.moveStock.MoveStockBillDetail;
import com.topisv.tms.entity.stock.tempStock.WarehouseTempStock;
import com.topisv.tms.entity.stock.tempStock.WarehouseTempStockDetail;
import com.topisv.tms.repository.UserDao;
import com.topisv.tms.repository.stock.CusStockDao;
import com.topisv.tms.repository.stock.moveStock.MoveStockBillDao;
import com.topisv.tms.repository.stock.moveStock.MoveStockBillDetailDao;
import com.topisv.tms.repository.stock.tempStock.WarehouseTempStockDao;
import com.topisv.tms.repository.stock.tempStock.WarehouseTempStockDetailDao;
import com.topisv.tms.service.AreaGroupService;
import com.topisv.tms.service.CustomersService;
import com.topisv.tms.service.EdiGoodsSkuService;
import com.topisv.tms.service.base.BaseService;

/**
 * 移库单_service
 * @author gh
 *
 */
@Component
@Transactional(readOnly = true)
public class MoveStockBillService extends BaseService{
	private static final Logger log = LoggerFactory.getLogger(MoveStockBillService.class);
	
	@Autowired
	private MoveStockBillDao moveStockBillDao;
	@Autowired
	private MoveStockBillDetailDao moveStockBillDetailDao;
	@Autowired
	private WarehouseTempStockDao wtsDao;
	@Autowired
	private WarehouseTempStockDetailDao wtsdDao;
	@Autowired
	private CusStockDao cusStockDao;
	@Autowired
	private EdiGoodsSkuService goodsService;
	@Autowired
	private CustomersService customersService;
	@Autowired
	private AreaGroupService warehouseService;
	@Autowired
	private UserDao userDao;
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void saveMoveStockBill(MoveStockBill msb) throws Exception {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		//List<CusStock> csList = cusStockDao.loadStockNoCustomerCode(msb.getWarehouseCode(), msb.getOutStockCode(), msb.getOutBoxCode(), msb.getSku());
		CusStock csList = cusStockDao.loadStock(msb.getCustomerCode(),msb.getWarehouseCode(), msb.getOutStockCode(), msb.getOutBoxCode(), msb.getSku());
		if(csList == null){
			throw new Exception("库存信息不存在!");
		}
		CusStock cusStock = csList;
		if("sale".equals(msb.getGoodsStatus())){
			if(cusStock.getSalesNum()<msb.getOutMoveNum()){
				log.error("库存扣减异常");
				throw new Exception( "库存不足!");
			}
		}else {
			if(cusStock.getUnusedNum()<msb.getOutMoveNum()){
				log.error("库存扣减异常");
				throw new Exception( "库存不足!");
			}
		}
		log.info("开始生成移库单！");
		String billCode="MOVE_"+msb.getWarehouseCode()+format.format(new Date())+new Random().nextInt(9);
		msb.setCustomerCode(cusStock.getCustomerCode());
		msb.setBillCode(billCode);//生成移库单编号
		moveStockBillDao.save(msb);
		log.info("移库单生成成功！");
		
		
		log.info("从库位中扣减库存！");
		
		if("sale".equals(msb.getGoodsStatus())){
			cusStock.setSalesNum(cusStock.getSalesNum()-msb.getOutMoveNum());
		}else {
	         cusStock.setUnusedNum(cusStock.getUnusedNum()-msb.getOutMoveNum());
		}
		cusStockDao.save(cusStock);
		
		log.info("库存扣减完毕！");
		
		
		log.info("移动到临时库存到！");
		WarehouseTempStock wts = new WarehouseTempStock();
		wts.setWarehouseCode(msb.getWarehouseCode());
		wts.setRefBillCode(msb.getBillCode());
		wts.setBillType("move");
		wts.setTotalSkuNum(msb.getOutMoveNum());
		
		wts.setCreateTime(new Date());
		wts.setCreateBy(msb.getCreateBy());
		wts.setStockCode("MOVE_TEMP_"+format.format(new Date())+new Random().nextInt(9));//生成临时库位编号
		wtsDao.save(wts);
		
		WarehouseTempStockDetail wtsd = new WarehouseTempStockDetail();
		wtsd.setWarehouseCode(msb.getWarehouseCode());
		wtsd.setCustomerCode(msb.getCustomerCode());
		wtsd.setSku(msb.getSku());
		wtsd.setStockCode(wts.getStockCode());
		wtsd.setSkuNum(msb.getOutMoveNum());
		wtsd.setGoodsStatus(msb.getGoodsStatus());//sale:销售库存 unsale:不可销售库存
		wtsdDao.save(wtsd);
		
		
		log.info("移动临时库存成功！");
	}
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String executeMoveStock(MoveStockBill toMsb) throws Exception{
		try {
			User worker=this.userDao.findByJobuuid(toMsb.getUpdateBy());
			log.info("开始执行移库操作！");
			MoveStockBill msb = moveStockBillDao.findOne(toMsb.getId());
			if(msb==null){
				throw new Exception("移库单不存在");
			}
			if(msb.getOutMoveNum()==null){msb.setOutMoveNum(0);}
			if(msb.getInMoveNum()==null){msb.setInMoveNum(0);}
			if(toMsb.getInMoveNum()==null){toMsb.setInMoveNum(0);}
			if(msb.getOutMoveNum()<msb.getInMoveNum()+toMsb.getInMoveNum()){
				throw new Exception("移入数量超出");
			}
			msb.setInStockCode(toMsb.getInStockCode());
			msb.setInBoxCode(toMsb.getInBoxCode());
			msb.setInMoveNum(msb.getInMoveNum()+toMsb.getInMoveNum());
			msb.setUpdateBy(toMsb.getUpdateBy());
			msb.setUpdateTime(toMsb.getUpdateTime());
			if(!msb.getInMoveNum().equals(msb.getOutMoveNum())){
				msb.setStatus("doing");
			}else {
				msb.setStatus("finish");
			}
			this.moveStockBillDao.save(msb);
			
			
			MoveStockBillDetail msbd = new MoveStockBillDetail();
			msbd.setWarehouseCode(msb.getWarehouseCode());
			msbd.setCustomerCode(msb.getCustomerCode());
			msbd.setBillCode(msb.getBillCode());
			msbd.setInStockCode(toMsb.getInStockCode());
			msbd.setInBoxCode(toMsb.getInBoxCode());
			msbd.setSku(toMsb.getSku());
			msbd.setInMoveNum(toMsb.getInMoveNum());
			msbd.setCreateBy(msb.getUpdateBy());
			msbd.setCreateTime(new Date());
			this.moveStockBillDetailDao.save(msbd);
			
			WarehouseTempStock wts = this.wtsDao.findByRefBillCode(msb.getBillCode());
			List<WarehouseTempStockDetail> wtsdList = this.wtsdDao.findByStockCode(wts.getStockCode());
			int totalNum = toMsb.getInMoveNum();
			for (WarehouseTempStockDetail wtsd : wtsdList) {
				if(msb.getGoodsStatus().equals(wtsd.getGoodsStatus())&&msb.getSku().equals(wtsd.getSku())){
					if(wtsd.getSkuNum()>=totalNum){
						wtsd.setSkuNum(wtsd.getSkuNum()-totalNum);
						totalNum = 0;
					}else {
						int tempNum = totalNum-wtsd.getSkuNum();
						wtsd.setSkuNum(tempNum);
						totalNum = tempNum;
					}
				}
			}
			if(totalNum!=0){
				throw new Exception("移出数量超出.");
			}
			wts.setTotalSkuNum(wts.getTotalSkuNum()-toMsb.getInMoveNum());
			wtsDao.save(wts);
			log.info("移动临时库存成功！");
			
			log.info("插入库存表");
			//List<CusStock> csList = cusStockDao.loadStockNoCustomerCode(msb.getWarehouseCode(), msb.getInStockCode(), msb.getInBoxCode(), msb.getSku());
			CusStock csList = cusStockDao.loadStock(msb.getCustomerCode(),msb.getWarehouseCode(), msb.getInStockCode(), msb.getInBoxCode(), msb.getSku());
			if(csList == null){
				CusStock cs = new CusStock();
				AreaGroup warehouse=this.warehouseService.findByGroupCode(msb.getWarehouseCode());
		   		cs.setWarehouse(warehouse);
				cs.setWarehouseCode(msb.getWarehouseCode());
				
				Customers customers = customersService.findByCustomerCode(msb.getCustomerCode());
				cs.setCustomerCode(customers.getCustomerCode());
				cs.setCustomer(customers);
				cs.setStockCode(toMsb.getInStockCode());
				cs.setBoxCode(toMsb.getInBoxCode());
				cs.setSku(msb.getSku());
				if("sale".equals(msb.getGoodsStatus())){
					cs.setSalesNum(toMsb.getInMoveNum());
					cs.setUnusedNum(0);
				}else {
					cs.setSalesNum(0);
					cs.setUnusedNum(toMsb.getInMoveNum());
				}
				cs.setOrderNum(0);
		   		cs.setLockedNum(0);
		   		cs.setTransportNum(0);
		   		cs.setAirNum(0);
		   		cs.setLastmodifyTime(new Date());
		   		cs.setLastopetator(worker);
				cs.setStockType("1");
				cusStockDao.save(cs);
				
			}else {
				CusStock cusStock = csList;
				if("sale".equals(msb.getGoodsStatus())){
					cusStock.setSalesNum(cusStock.getSalesNum()+toMsb.getInMoveNum());
				}else {
					cusStock.setUnusedNum(cusStock.getUnusedNum()+toMsb.getInMoveNum());
				}
			}
			log.info("插入库存表");
		}catch(Exception e){
			throw new Exception("系统异常");
		}
		return "success";
	}
	
	public List<MoveStockBill> findNoFinishMoveBill(String warehouseCodes,String jobuuid) throws Exception {
		List<String> warehouseCodeList = new ArrayList<String>(); 
		for (String wc : warehouseCodes.split(":")) {
			warehouseCodeList.add(wc);
		}
		List<MoveStockBill> moveList = moveStockBillDao.findNoFinishMoveBill( warehouseCodeList,jobuuid);
		HashMap<String,Object> cacheMap = new HashMap<String,Object>();
		for (MoveStockBill msb : moveList) {
			String message = setName(msb,cacheMap);
			if(!"success".equals(message)){
				throw new Exception(message);
			}
			
		}
		return moveList;
	}
	
	public String setName(MoveStockBill msb,HashMap<String,Object> cacheMap){
		EdiGoodsSku goodsSku = null;
		String skuKey = "goods_"+msb.getCustomerCode()+"_"+msb.getSku();
		if(!cacheMap.containsKey(skuKey)){
			goodsSku = goodsService.findByCustomerCodeAndSku(msb.getCustomerCode(), msb.getSku());
			cacheMap.put(skuKey, goodsSku);
		}else{
			goodsSku = (EdiGoodsSku)cacheMap.get(skuKey);
		}
		if(goodsSku!=null){
			msb.setSkuName(goodsSku.getSkuName());
		}else {
			log.info("sku:"+msb.getSku()+")商品信息未配置");
			msb.setSkuName("");
//			return "商品信息未配置";
			return "success";
		}
		
		Customers customers = null;
		String customerKey = "customers_"+msb.getCustomerCode();
		if(!cacheMap.containsKey(customerKey)){
			customers = customersService.findByCustomerCode(msb.getCustomerCode());
			cacheMap.put(customerKey, customers);
		}else{
			customers = (Customers)cacheMap.get(customerKey);
		}
		if(customers!=null){
			msb.setCustomerName(customers.getCustomerName());
		}else {
			log.info("(customerCode:"+msb.getCustomerCode()+")商家信息未配置");
			return "商家信息未配置";
		}
		
		
		AreaGroup areaGroup = null;
		String warehouseKey = "areaGroup_"+msb.getWarehouseCode();
		if(!cacheMap.containsKey(warehouseKey)){
			areaGroup = warehouseService.findByGroupCode(msb.getWarehouseCode());
			cacheMap.put(warehouseKey, areaGroup);
		}else{
			areaGroup = (AreaGroup)cacheMap.get(warehouseKey);
		}
		if(areaGroup!=null){
			msb.setWarehouseName(areaGroup.getGroupName());
		}else {
			log.info("(warehouseCode:"+msb.getWarehouseCode()+")仓库信息未配置");
			return "仓库信息未配置";
		}
		return "success";
		
	}
	
	public MoveStockBill findOne(Long id) {
		MoveStockBill msb =  moveStockBillDao.findOne(id);
		HashMap<String,Object> cacheMap = new HashMap<String,Object>();
		this.setName(msb, cacheMap);
		return msb;
	}
	
}
